home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
pascal
/
tpl60n19.zip
/
TESTPRGS.ZIP
/
UNIT2.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1992-02-27
|
25KB
|
822 lines
{$a+,n-,x-,s-,i-,r-,b-,v-}
unit Unit2;
interface
uses mainvars;
procedure mile70170;
implementation
procedure mile70170;
begin
{=============================================}
Milestone := 70;
{=============================================}
writeln;
writeln ('Running test of square root(x).');
TestCondition (Failure, (Zero = sqrt (Zero))
and (- Zero = sqrt (- Zero))
and (One = sqrt (One)), ' Square root of 0.0, -0.0 or 1.0 wrong '
);
MinSqrtError := Zero;
MaxSqrtError := Zero;
J := 0;
X := Radix;
OneUlp := U2;
SqrtXMinX (SeriousDefect);
X := BInverse;
OneUlp := BInverse * U1;
SqrtXMinX (SeriousDefect);
X := U1;
OneUlp := U1 * U1;
SqrtXMinX (SeriousDefect);
if J <> 0 then
begin
NoErrors [SeriousDefect] := NoErrors [SeriousDefect] + 1;
Pause;
end;
writeln ('Testing if sqrt(X * X) = X for ', NoTrials, ' integers X.');
J := 0;
X := Two;
Y := Radix;
if (Radix <> One) then
repeat
X := Y;
Y := Radix * Y;
until (Y - X >= NoTrials);
OneUlp := X * U2;
I := 1;
Continue := true;
while (I <= NoTrials) and Continue do (* dgh: 10 --> NoTrials *)
begin
X := X + One;
SqrtXMinX (Defect);
if J > 0 then
begin
Continue := false;
NoErrors [Defect] := NoErrors [Defect] + 1;
end;
I := I + 1;
end;
writeln ('Test for Sqrt Monotonicity.');
I := - 1;
X := BMinusU2;
Y := Radix;
Z := Radix + Radix * U2;
NotMonot := false;
Monot := false;
while not (NotMonot or Monot) do
begin
I := I + 1;
X := sqrt (X);
Q := sqrt (Y);
Z := sqrt (Z);
if (X > Q) or (Q > Z) then
NotMonot := true
else
begin
Q := Int (Q + Half);
if (I > 0) or (Radix = Q * Q) then
Monot := true
else if I > 0 then
begin
if I > 1 then
Monot := true
else
begin
Y := Y * BInverse;
X := Y - U1;
Z := Y + U1;
end
end
else
begin
Y := Q;
X := Y - U2;
Z := Y + U2;
end
end
end;
if Monot then
writeln ('Sqrt has passed a test for Monotonicity.')
else
begin
NoErrors [Defect] := NoErrors [Defect] + 1;
writeln('DEFECT: Sqrt(X) is non-monotonic for X near ', Y);
end;
{=============================================}
Milestone := 80;
{=============================================}
MinSqrtError := MinSqrtError + Half;
MaxSqrtError := MaxSqrtError - Half;
Y := (sqrt (One + U2) - One) / U2;
SqrtError := (Y - One) + U2 / Eight;
if SqrtError > MaxSqrtError then
MaxSqrtError := SqrtError;
SqrtError := Y + U2 / Eight;
if SqrtError < MinSqrtError then
MinSqrtError := SqrtError;
Y := ((sqrt (F9) - U2) - (One - U2)) / U1;
SqrtError := Y + U1 / Eight;
if SqrtError > MaxSqrtError then
MaxSqrtError := SqrtError;
SqrtError := (Y + One) + U1 / Eight;
if SqrtError < MinSqrtError then
MinSqrtError := SqrtError;
OneUlp := U2;
X := OneUlp;
for Index := 1 to 3 do
begin
Y := sqrt ((X + U1 + X) + F9);
Y := ((Y - U2) - ((One - U2) + X)) / OneUlp;
Z := ((U1 - X) + F9) * Half * X * X / OneUlp;
SqrtError := (Y + Half) + Z;
if SqrtError < MinSqrtError then
MinSqrtError := SqrtError;
SqrtError := (Y - Half) + Z;
if SqrtError > MaxSqrtError then
MaxSqrtError := SqrtError;
if ((Index = 1) or (Index = 3)) then
X := OneUlp * Sign (X) * Int (Eight / (Nine * sqrt (OneUlp)))
else
begin
OneUlp := U1;
X := - OneUlp;
end;
end;
{=============================================}
Milestone := 85;
{=============================================}
SquareRootWrong := false;
AnomolousArithmetic := false;
RSqrt := Other; (* ~dgh *)
if Radix <> One then
begin
writeln ('Testing whether sqrt is rounded or chopped: ');
D := Int (Half + Power (Radix, One + Precision - Int (Precision)))
;
{ ... = Radix^(1 + fract) if Precision = integer + fract. }
X := D / Radix;
Y := D / A1;
if (X <> Int (X)) or (Y <> Int (Y)) then
begin
AnomolousArithmetic := true;
end
else
begin
X := Zero;
Z2 := X;
Y := One;
Y2 := Y;
Z1 := Radix - One;
FourD := Four * D;
repeat
if Y2 > Z2 then
begin
Q := Radix;
Y1 := Y;
repeat
X1 := abs (Q + Int (Half - Q / Y1) * Y1);
Q := Y1;
Y1 := X1;
until X1 <= Zero;
if Q <= One then
begin
Z2 := Y2;
Z := Y;
end;
end;
Y := Y + Two;
X := X + Eight;
Y2 := Y2 + X;
if Y2 >= FourD then
Y2 := Y2 - FourD;
until Y >= D;
X8 := FourD - Z2;
Q := (X8 + Z * Z) / FourD;
X8 := X8 / Eight;
if Q <> Int (Q) then
AnomolousArithmetic := true
else
begin
Break := false;
repeat
X := Z1 * Z;
X := X - Int (X / Radix) * Radix;
if X = One then
Break := true
else
Z1 := Z1 - One;
until Break or (Z1 <= 0);
if (Z1 <= 0) and (not Break) then
AnomolousArithmetic := true
else
begin
if Z1 > RadixD2 then
Z1 := Z1 - Radix;
repeat
NewD;
until U2 * D >= F9;
if D * Radix - D <> W - D then
AnomolousArithmetic := true
else
begin
Z2 := D;
I := 0;
Y := D + (One + Z) * Half;
X := D + Z + Q;
SubRout3750;
Y := D + (One - Z) * Half + D;
X := D - Z + D;
X := X + Q + X;
SubRout3750;
NewD;
if D - Z2 <> W - Z2 then
AnomolousArithmetic := true
else
begin
Y := (D - Z2) + (Z2 + (One - Z) * Half);
X := (D - Z2) + (Z2 - Z + Q);
SubRout3750;
Y := (One + Z) * Half;
X := Q;
SubRout3750;
if I = 0 then
AnomolousArithmetic := true;
end
end
end
end
end;
if (I = 0) or AnomolousArithmetic then
begin
NoErrors [Failure] := NoErrors [Failure] + 1;
writeln ('FAILURE: Anomolous arithmetic with ',
'integer < Radix^Precision = ');
writeln (W, ' fails test whether sqrt rounds or chops.');
SquareRootWrong := true;
end
end;
if not AnomolousArithmetic then
begin
if not ((MinSqrtError < 0) or (MaxSqrtError > 0)) then
begin
RSqrt := Rounded;
writeln ('Square root appears to be correctly rounded.');
end
else if (MaxSqrtError + U2 > U2 - Half) or (MinSqrtError > Half)
or (MinSqrtError + Radix < Half) then
SquareRootWrong := true
else
begin
RSqrt := Chopped;
writeln ('Square root appears to be chopped.');
end;
end